Computer operating systems are very complex computer programs. When developing or modifying an operating system, it is critical that the operating system be thoroughly tested. The testing of an operating system typically involves several testing phases. First, the programmer who writes a program for the operating system performs "unit testing." This unit testing ensures that the program functions as intended by the programmer. Second, the programmers who developed various programs perform integration testing. This integration testing ensures that the various programs function together correctly. Third, the developer of the operating system performs alpha testing of the operating system. During alpha testing, application programs are executed with the operating system and any anomalies are logged for later correction. Finally, end users of the operating system perform beta testing. The beta testing ensures that the operating system will function correctly in the end user's environment.
The testing of an operating system can be very time consuming and expensive. Furthermore, it is virtually impossible to ensure that the operating system is error free. Generally, operating system developers concentrate on ensuring that the operating system will function correctly with "standard applications." A standard application is an application program that a typical user of the operating system may use. By testing with these standard applications, a developer can help ensure the operating system will function correctly in most typical situations.
Certain operating systems are referred to as message-driven operating systems. One such operating system is Windows 3.1, developed by Microsoft Corporation. A description of Windows 3.1 is provided in the Software Development Kit for Windows 3.1, which is available from Microsoft Corporation and is hereby incorporated by reference. The Windows operating system provides a windowing environment for applications that support a graphical user interface (GUI). FIG. 1 is a block diagram illustrating the messaging architecture of a typical message-driven operating system. An application program 110 contains a main procedure 111 and a window procedure 112. When the application program 110 is executed under the control of the operating system, control is passed to the main procedure 111. The main procedure 111 typically creates and displays a window and then enters a message loop 113. When executing the message loop, the application program 110 waits to receive a message from the operating system 120 indicating an external event (e.g., key down). The messages received by the message loop are referred to as posted messages. When a message is received, the application program 110 processes the message by requesting the operating system 120 to dispatch the message to the appropriate window procedure. The application program 110 includes a window procedure 112 for each window that is displayed on display monitor 130. A window procedure is invoked by the operating system when a message is dispatched to that window or when the operating system sends (discussed below) a message to that window. The window procedure decodes the message and processes the message accordingly. For example, a message dispatched to the window procedure may indicate that a character has been depressed on the keyboard when the window has the focus. A window that has the focus receives all keyboard and mouse inputs.
The operating system 120 provides various functions to application programs that provide services to the application programs. These functions may include: RegisterClass, CreateWindow, ShowWindow, GetMessage, DispatchMessage, and DefWindowProc. These functions are collectively referred to as the application programming interface (API) provided by the operating system, and each function may be individually referred to as an API. During execution of the application program 110, the application program invokes the various functions provided by the operating system. These functions are typically stored in a dynamic link library. When the application program is initially loaded into memory, it dynamically links to each of the functions it uses. As shown by the main procedure 111, the application program 110 initially invokes the function RegisterClass to register a window class with the operating system. Each window class has an associated window procedure for processing messages that are sent to a window. The operating system maintains a window class table 122, which correlates a window class with its window procedure. When a window class is registered, the operating system stores the address of the window procedure in the window class table 122. When a message is to be sent to a window, the operating system invokes the associated window procedure passing it various parameters including the type of the message.
A window procedure is a type of a callback routine. A callback routine is a routine that is part of the application program but is invoked directly by the operating system. The application program provides the operating system with the address of a callback routine that is developed to perform application-specific processing. The operating system then invokes the callback routine to perform the processing.
The operating system also maintains a message queue 121 for the application program 110. The message queue 121 contains messages that are posted to the application program. Each invocation of the function GetMessage in the message loop 113 retrieves a message from the message queue 121. The posted messages in the message queue typically correspond to external events such as mouse movement. When the operating system detects mouse movement over the window on the display monitor 130, the operating system posts a message to the message queue for the application program. The application program during the message loop retrieves each posted message and invokes the function DispatchMessage to process the message. The function DispatchMessage determines which window procedure the message is directed to and sends the message to that window by invoking its window procedure. Not all messages are posted, dispatched, and then sent to the window procedure. The operating system sometimes sends messages directly to a window procedure, without first posting the message to the message queue. For example, when a window is first created, the operating system may send a create message (WM.sub.-- CREATE) to the window procedure for that window. This message allows the window procedure to perform initialization of the window.